﻿using Common.Filters;
using Common.Models;
using Library.Entity;
using Microsoft.AspNetCore.Authorization;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.OpenApi.Models;
using NLog;
using NLog.Web;
using Swashbuckle.AspNetCore.SwaggerUI;
using System.Reflection;
using Wallpaper.Authorization;
using Wallpaper.Authorization.Handlers;
using Wallpaper.Data.Context;
using Wallpaper.Data.Dal;
using Wallpaper.Data.IDal;
using Wallpaper.Models;
using Wallpaper.Services.IService;
using Wallpaper.Services.Service;
using Wallpaper.Services.Socket;
using WallpaperApi.Configurations;
using WallpaperApi.Filter;
using WallpaperApi.Middleware;

namespace wallpaperApi
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();
            logger.Debug("init main");
            var builder = WebApplication.CreateBuilder(args);

            // ========== 1. 日志配置 ==========
            builder.Logging.ClearProviders();
            builder.Host.UseNLog();

            // ========== 2. 控制器配置 ==========
            builder.Services.AddControllers(options =>
            {
                //  全局注册模型验证过滤器 
                options.Filters.Add<ModelValidationFilter>();
            });

            // ========== 3. Swagger/OpenAPI配置 ==========
            builder.Services.AddEndpointsApiExplorer();
            builder.Services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo
                {
                    Title = "壁纸小程序 API",
                    Version = "v1",
                    Description = "壁纸小程序 Web API 接口文档",
                    Contact = new OpenApiContact
                    {
                        Name = "开发团队",
                        Email = "2235557843@qq.com"
                    },
                    License = new OpenApiLicense
                    {
                        Name = "MIT License"
                    }
                });

                // 启用XML注释
                var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
                if (File.Exists(xmlPath))
                {
                    c.IncludeXmlComments(xmlPath, true);
                }

                // 为模型类也添加XML注释
                var modelsXmlPath = Path.Combine(AppContext.BaseDirectory, "Wallpaper.Models.xml");
                if (File.Exists(modelsXmlPath))
                {
                    c.IncludeXmlComments(modelsXmlPath);
                }

                // JWT Bearer Token配置
                c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                {
                    Description = "JWT授权 header使用Bearer scheme。示例: \"Authorization: Bearer {token}\"",
                    Name = "Authorization",
                    In = ParameterLocation.Header,
                    Type = SecuritySchemeType.Http,
                    Scheme = "Bearer",
                    BearerFormat = "JWT"
                });

                c.AddSecurityRequirement(new OpenApiSecurityRequirement
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference
                            {
                                Type = ReferenceType.SecurityScheme,
                                Id = "Bearer"
                            }
                        },
                        new string[] { }
                    }
                });

                // 设置接口排序
                c.OrderActionsBy(apiDesc => $"{apiDesc.ActionDescriptor.RouteValues["controller"]}_{apiDesc.HttpMethod}");

                // 设置枚举显示为字符串（如果不需要可以删除这行）
                 c.SchemaFilter<EnumSchemaFilter>();
            });

            // ========== 4. 数据库上下文配置 ==========
            //builder.Services.AddDbContext<WallpaperDbContext>(options =>
            //    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
            // ========== 4. 数据库上下文配置 ==========
            builder.Services.AddDbContext<WallpaperDbContext>(options =>
            {
                options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"));

                // 输出SQL到控制台
                options.LogTo(Console.WriteLine,
                    new[] { DbLoggerCategory.Database.Command.Name },
                    Microsoft.Extensions.Logging.LogLevel.Information,
                    DbContextLoggerOptions.SingleLine | DbContextLoggerOptions.UtcTime);

                // 开发环境启用详细日志
                if (builder.Environment.IsDevelopment())
                {
                    options.EnableSensitiveDataLogging();
                    options.EnableDetailedErrors();
                }
            });



            //Minio配置
            builder.Services.Configure<MinioConfig>(builder.Configuration.GetSection("MinioConfig"));
            // ========== 5. 依赖注入配置 ==========
            // Data Access Layer


            //
            // 注册配置
            builder.Services.Configure<AuthorizationSettings>(
                builder.Configuration.GetSection("Authorization"));

            // JWT配置（添加在这里）
            builder.Services.Configure<JwtOpt>(builder.Configuration.GetSection("JwtOpt"));
            builder.Services.AddScoped<IJwtService, JwtService>();
            // 注册HttpClient
            builder.Services.AddHttpClient<IWeChatService, WeChatService>();

            //  添加 ModelValidationFilter 注册
            builder.Services.AddScoped<ModelValidationFilter>();

            builder.Services.AddScoped<IUserDal, UserDal>();
            builder.Services.AddScoped<ICategoryDal, CategoryDal>();
            builder.Services.AddScoped<IAdminDal, AdminDal>();
            builder.Services.AddScoped<IDownloadRecordDal, DownloadRecordDal>();
            builder.Services.AddScoped<ITagDal, TagDal>();
            builder.Services.AddScoped<IUserFavoriteDal, UserFavoriteDal>();
            builder.Services.AddScoped<IWallpaperDal, WallpaperDal>();
            builder.Services.AddScoped<ICarouselDal, CarouselDal>();
            builder.Services.AddScoped<IMenuDal, MenuDal>();
            builder.Services.AddScoped<IRoleDal, RoleDal>();
            builder.Services.AddScoped<IPermissionDal, PermissionDal>();
            builder.Services.AddScoped<IMessageDal, MessageDal>();
            builder.Services.AddScoped<IUserMessageDal, UserMessageDal>();
            

            // Business Layer
            builder.Services.AddScoped<IMinioService, MinioService>();
            builder.Services.AddScoped<IUserService, UserService>();
            builder.Services.AddScoped<ICategoryService, CategoryService>();
            builder.Services.AddScoped<IAdminService, AdminService>();
            builder.Services.AddScoped<IDownloadRecordService, DownloadRecordService>();
            builder.Services.AddScoped<ITagService, TagService>();
            builder.Services.AddScoped<IUserFavoriteService, UserFavoriteService>();
            builder.Services.AddScoped<IWallpaperService, WallpaperService>();
            builder.Services.AddScoped<ICarouselService, CarouselService>();
            builder.Services.AddScoped<IMenuService, MenuService>();
            builder.Services.AddScoped<IRoleService, RoleService>();
            builder.Services.AddScoped<IPermissionService, PermissionService>();
            builder.Services.AddScoped<IMessageService, MessageService>();
           
            
            builder.Services.AddScoped<IAuthorizationHandler, PermissionHandler>();

            //// 配置身份验证
            //builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            //    .AddJwtBearer(options =>
            //    {
            //        var jwtOpt = builder.Configuration.GetSection("JwtOpt").Get<JwtOpt>();
            //        options.TokenValidationParameters = new TokenValidationParameters
            //        {
            //            ValidateIssuer = true,
            //            ValidateAudience = true,
            //            ValidateLifetime = true,
            //            ValidateIssuerSigningKey = true,
            //            ValidIssuer = jwtOpt?.Issuer,
            //            ValidAudience = jwtOpt?.Audience,
            //            IssuerSigningKey = new SymmetricSecurityKey(
            //                Encoding.UTF8.GetBytes(jwtOpt?.SecurityKey ?? "default-key"))
            //        };

            //        // 添加 JWT 认证事件处理
            //        options.Events = new JwtBearerEvents
            //        {
            //            OnAuthenticationFailed = context =>
            //            {
            //                var logger = context.HttpContext.RequestServices.GetRequiredService<ILogger<Program>>();

            //                // 检查响应是否已经开始
            //                if (context.Response.HasStarted)
            //                {
            //                    logger.LogWarning("响应已开始，跳过认证失败处理");
            //                    return Task.CompletedTask;
            //                }

            //                string errorMessage;
            //                if (context.Exception is SecurityTokenExpiredException)
            //                {
            //                    errorMessage = "登录状态已过期，请重新登录";
            //                    logger.LogWarning("JWT Token 已过期");
            //                }
            //                else
            //                {
            //                    errorMessage = "请先登录";
            //                    logger.LogWarning("JWT 认证失败: {Error}", context.Exception.Message);
            //                }

            //                context.Response.StatusCode = 401;
            //                context.Response.ContentType = "application/json";
            //                var result = JsonSerializer.Serialize(new
            //                {
            //                    isSuccess = false,
            //                    message = errorMessage,
            //                    code = 401,
            //                });
            //                return context.Response.WriteAsync(result);
            //            },
            //            OnChallenge = context =>
            //            {
            //                var logger = context.HttpContext.RequestServices.GetRequiredService<ILogger<Program>>();

            //                // 检查响应是否已经开始
            //                if (context.Response.HasStarted)
            //                {
            //                    logger.LogWarning("响应已开始，跳过认证挑战处理");
            //                    return Task.CompletedTask;
            //                }

            //                logger.LogWarning("JWT 认证挑战: {Error}", context.ErrorDescription);

            //                // 直接设置响应，不调用 HandleResponse
            //                context.Response.StatusCode = 401;
            //                context.Response.ContentType = "application/json";

            //                var result = JsonSerializer.Serialize(new ApiResponse<Object>
            //                {
            //                    IsSuccess = false,
            //                    Message = "请先登录",
            //                    Code = 401
            //                });
            //                return context.Response.WriteAsync(result);
            //            }
            //        };
            //    });

            // JWT 认证配置
            builder.Services.ConfigureJwtAuthentication(builder.Configuration);

            builder.Services.AddAuthorization(options =>
            {
                // 如果你希望动态注册所有权限，可以从数据库加载 Permissions 表：
                using var scope = builder.Services.BuildServiceProvider().CreateScope();
                var db = scope.ServiceProvider.GetRequiredService<WallpaperDbContext>();
                var permissions = db.Permissions.Select(p => p.Code).ToList();

                foreach (var code in permissions)
                {
                    options.AddPolicy(code, policy => policy.Requirements.Add(new PermissionRequirement(code)));
                }
            });

            // ========== 6. 其他服务配置 ==========

            //跨域
            var AllowFrontend = "_allowFrontend";

            builder.Services.AddCors(options =>
            {
                options.AddPolicy(name: AllowFrontend,
                                  policy =>
                                  {
                                      policy.WithOrigins("http://localhost:5173",
                                          "https://localhost:5173"
                                          )  // 前端开发地址           
                                            .AllowAnyHeader()
                                            .AllowAnyMethod()
                                            .AllowCredentials();
                                  });
            });

        

            var app = builder.Build();

            // ========== 中间件管道配置 ==========

            app.UseWebSockets();

            // 开发环境配置
            if (app.Environment.IsDevelopment())
            {
                app.UseSwagger();
                app.UseSwaggerUI(c =>
                {
                    c.SwaggerEndpoint("/swagger/v1/swagger.json", "壁纸Web API v1");
                    c.DefaultModelsExpandDepth(-1); // 默认折叠模型
                    c.DocExpansion(DocExpansion.List); // 展开所有分类，但折叠具体操作（推荐）
                    c.DisplayRequestDuration(); // 显示请求耗时
                    c.EnableFilter(); // 启用筛选器
                    c.EnableDeepLinking(); // 启用深度链接
                    c.EnablePersistAuthorization(); // 保持授权状态
                });

                // 在开发环境下，可以同时使用详细错误页面和全局异常处理
                app.UseDeveloperExceptionPage();
            }

            // 生产环境配置
            if (app.Environment.IsProduction())
            {
                app.UseExceptionHandler("/error");
                app.UseHsts();
            }

            // 只在生产环境启用 HTTPS 重定向
            //if (app.Environment.IsProduction())
            //{
            //    app.UseHttpsRedirection();
            //}

            if (!app.Environment.IsDevelopment())
            {
                app.UseHsts(); // 只在生产环境启用 HSTS
            }

            app.UseRouting();
            app.Map("/ws", async context =>
            {
                if (context.WebSockets.IsWebSocketRequest)
                {
                    // 从请求中获取 userId（假设通过查询字符串传递 userId）
                    var userId = context.Request.Query["userId"].ToString();
                    if (string.IsNullOrEmpty(userId))
                    {
                        context.Response.StatusCode = 400;
                        await context.Response.WriteAsync("UserId is required");
                        return;
                    }

                    // 接受 WebSocket 连接
                    var socket = await context.WebSockets.AcceptWebSocketAsync();

                    // 将 WebSocket 和用户ID关联
                    await WebSocketService.HandleWebSocketAsync(socket, userId);
                }
                else
                {
                    context.Response.StatusCode = 400;
                    await context.Response.WriteAsync("Invalid WebSocket request");
                }
            });

            app.UseHttpsRedirection();
            app.UseCors(AllowFrontend); // 启用CORS
           
            // 全局异常处理中间件应该在认证和授权之前
            app.UseMiddleware<GlobalExceptionHandlerMiddleware>();


            app.UseAuthentication(); // 添加这行：启用认证
            app.UseAuthorization();

            
            app.MapControllers();
            // ========== 启动应用 ==========
            app.Run();
        }
    }
}